;
import  '../../core/fun.js';
/**
 *在main.js 中 把db实例化 注入 Vue 对象 的$db 子对象 
 *
 *通过$db 实现对数据库的使用 
 
 用法:
  先实例化db对象
  然后更新表结构 
  因为更新表结构的时间不确定 ,而js 又是异步模板
  如果需要立即操作 必须在更新表结构后
 */
var DB = {


	TF开始: "begin",
	TF提交: "commit",
	TF回滚: "rollback",
	键值对表: "sys_kv",
	//console.log(self,this);
	//this.总长度=0; //pack[0，4)
	create(数据库别名) {


		let self = this;
		self.dbName = 数据库别名;
		self.dbpath = null;
		self.type = 0;
		self._db = null;
		self._表池 = {};
		self._表池key = {};
		/**
		 * 如果修改表结构就必须修改版本
		 */
		function open(版本, 建表工作, 打开数据库后回调, 异常回调) {
			//1 +2 是 sql语句
			//3 是 indexeddb
			if (window.hasOwnProperty("indexedDB")) {
				self.dbPath = self.dbName;
				self.type = 3;
				const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window
					.msIndexedDB;
				let req = indexedDB.open(self.dbName, 版本);
				req.onsuccess = function(e) {
					self._db = e.target.result;
					打开数据库后回调 && 打开数据库后回调();
				}
				req.onupgradeneeded = function(e) {
					self._db = e.target.result;
					console.log("indexedDB数据库[" + self.dbName + "]打开成功", self._db);
					//indexeddb 规定 createtable 只能在这个地方调用 不能在onsuccess中调用
					建表工作 && 建表工作();
				};
				req.onerror = function(e) {
					异常回调 && 异常回调();
				}

			} else if (window.hasOwnProperty("plus")) {
				self._db = plus.sqlite;
				self.dbPath = '_doc/' + self.dbName + '.db'
				self.type = 1;
				self._db.openDatabase({
					name: self.dbName,
					path: self.dbPath,
					success: function(e) {
						console.log('打开plus.sqlite数据库成功');
						建表工作 && 建表工作();
						打开数据库后回调 && 打开数据库后回调();
					},
					fail: function(e) {
						console.log(e, '打开plus.sqlite数据库失败');
						异常回调 && 异常回调(e);
					}
				});
			} else if (window.hasOwnProperty("openDatabase")) {
				//
				self.dbPath = self.dbName + '.db';
				self.type = 2;
				self._db = window.openDatabase(self.dbPath, '1.0', self.dbName, 50 * 1000 * 1000);
				console.log("使用webdb数据库")
				建表工作 && 建表工作();
				打开数据库后回调 && 打开数据库后回调();

			} else {
				console.log("环境不支持indexedDB,sqlite或webdb");
				异常回调 && 异常回调();
				self.type = 0;

			}
		}

		/**
			 * 表属性 {		
				键: 'ssn', 
				自增: true ,
				字段:{
					字段名:类型				
				}
			 }
			 */
		self.f建表 = function(表名, 表属性) {

			if (self.type == 3) {
				// { keyPath: 'ssn', autoIncrement: true }

				if (!self._db.objectStoreNames.contains(表名)) {
					let obj = {}
					if (表属性.hasOwnProperty("键")) {
						obj = {
							keyPath: 表属性["键"]
						};
						self._表池key[表名] = 表属性["键"];
					}
					if (表属性.hasOwnProperty("自增")) {
						obj = Object.assign(obj, {
							autoIncrement: 表属性["自增"]
						});
					}

					self._db.createObjectStore(表名, obj);
				}
			} else if (self.type == 1 || self.type == 2) {
				let str = "";
				let keyPath = null;
				let autoadd = false;
				if (表属性.hasOwnProperty("键")) {
					keyPath = 表属性["键"];
					self._表池key[表名] = 表属性["键"];
				}
				if (表属性.hasOwnProperty("自增")) {
					autoadd = true;
				}
				if (表属性.hasOwnProperty("字段")) {
					Object.getOwnPropertyNames(表属性.字段).forEach((field) => {
						let type = 表属性.字段[field].toLowerCase();
						str = str + ", " + field;
						if (type.startsWith("int")) {
							str += " integer "
						} else if (type.indexOf("char") > -1) {
							str += " Text"
						} else if (type.startsWith("text")) {
							str += " Text"
						}
						if (field == keyPath)
							str += " PRIMARY KEY";
						if (autoadd)
							str += " autoincrement";
					});
				}
				let sql = "create table if not exists " + 表名 + "( " + str.substring(1) + ")";
				execSql(sql, 设置后回调);
			}
		}
		self.isOpen = function(回调函数, err) {
			if (self.type == 1) {
				let res = self._db.isOpenDatabase({
					name: self.dbName,
					path: self.dbPath
				});
				if (res) {
					console.log(res, '数据库已打开');
					回调函数 && 回调函数();
				} else {
					console.log(res, '数据库未打开');
					err && err(e);
				}
			}
		}
		self.closedb = function() {
			if (self.type == 1) {
				self._db.closeDatabase({
					name: self.dbName,
					success: function(e) {
						console.log(JSON.stringify(e), '数据库已经关闭!');
					},
					fail: function(e) {
						console.log('关闭失败: ' + JSON.stringify(e));
					}
				});
			}
		}

		self.transaction = function(事务名, 事务函数执行, 异常回调) {

			if (self.type == 1) {
				self._db.transaction({
					name: self.dbName,
					operation: 'begin',
					success: function(e) {
						事务函数执行 && 事务函数执行(data);
					},
					fail: function(e) {
						console.log(事务名 + '失败: ' + JSON.stringify(e));
						异常回调 && 异常回调(e);
					}
				});
			} else {
				console.log("目前环境 不支持 事务操作")
			}
		}

		function execSql(sql, 执行成功回调, 执行异常回调) {

			if (self.type == 1) {
				self._db.executeSql({
					name: self.dbName,
					sql: sql,
					success: function(data) {
						执行成功回调 && 执行成功回调(data);
					},
					fail: function(e) {
						console.log('异常日志: ' + e);
						执行异常回调 && 执行异常回调(e);
					}
				});
			} else if (self.type == 2) {
				let success = function(tx, result) {
					if (执行成功回调) {
						执行成功回调(result);
					}
				};
				let fail = function(tx, err) {
					//console.log(err.source + "::" + err.message);
					if (执行异常回调) {
						执行异常回调(error);
					}
				}
				self._db.transaction(function(tx) {
					tx.executeSql(sql, [], success, fail);
				})
			}

		}

		function select(sql, 查询成功回调, 查询异常回调) {
			if (self.type == 1) {
				self._db.selectSql({
					name: self.dbName,
					sql: sql,
					success: function(data) {
						查询成功回调 && 查询成功回调(data);
					},
					fail: function(e) {
						console.log('失败日志: ' + JSON.stringify(e));
						查询异常回调 && 查询异常回调(e);
					}
				});

				// return new Promise((resolve, reject) => {
				// 		try {
				// 			self._db.selectSql({
				// 				name: self.dbName,
				// 				sql: sql,
				// 				success: function(data) {
				// 					resolve(data);

				// 				},
				// 				fail: function(e) {
				// 					reject(e);									
				// 				}
				// 			});
				// 		} catch (e) {
				// 			resolve([e])
				// 		}
				// 	});
			} else if (self.type == 2) {
				let success = function(tx, result) {
					if (执行成功回调) {
						执行成功回调(result);
					}
				};
				let fail = function(tx, err) {
					console.log(err.source + "::" + err.message);
					if (执行异常回调) {
						执行异常回调(error);
					}
				}
				self._db.transaction(function(tx) {
					tx.executeSql(sql, [], success, fail);
				})
			}
		}



		self.f删除表 = function(表名) {
			if (self.type == 3) {
				if (self._db.objectStoreNames.contains(表名)) {
					self._db.deleteObjectStore(表名);
					//console.log(表名, 表属性)
				}
			} else if (self.type == 1 || self.type == 2) {
				execSql("drop TABLE IF EXISTS " + 表名);
			}
		}

		//创建表，时 indexeddb规定 建表语句子能在 onupgradeneeded 中
		function f建表集(表集) {
			if (self.type == 0) return false;
			for (var 表名 in 表集) {
				self.f建表(表名, 表集[表名]);
			}
			return true;
		}

		function f建索引(表名, 字段) {
			if (self.type == 3) {
				let tx = self._db.transaction(表名, "readwrite");
				const store = tx.objectStore(表名);
				store.createIndex("idx_" + 字段, 字段);
			} else if (self.type == 1 || self.type == 2) {
				let sql = "CREATE INDEX idx_" + 表名 + 字段 + "	ON " + 表名 + " (字段)";
				self.execSql(sql);
			}
		}
		//type=3 专用
		function get对象表(表名) {
			if (self._表池.hasOwnProperty(表名)) {
				return self._表池[表名];
			} else {
				const tx = self._db.transaction(表名, "readwrite");
				const store = tx.objectStore(表名);
				self._表池[表名] = store;
				return store;
			}
		}
		self.f遍历集合 = function(表名或select, 遍历) {
			if (self.type == 3) {
				var objectStore = get对象表(表名或select);
				//console.log("集合")
				objectStore.openCursor().onsuccess = function(event) {
					var cursor = event.target.result;
					if (cursor) {
						遍历 && 遍历(cursor.value); //cursor.value 
						cursor.continue();
					}
				};
			} else if (self.type == 1 || self.type == 2) {
				var sql = "select * from " + 表名或select;
				select(sql, function(list) {
					for (let a in list) {
						获取回调 && 获取回调(list[a]);
					}
				});
			}
		}
		self.f插入对象 = function(表名, obj, 成功回调) {
			if (self.type == 0) return false;
			if (self.type == 3) {
				let store = get对象表(表名);
				store.add(obj).onsuccess = function(e) {
					成功回调 && 成功回调(e);
				};
			} else if (self.type == 1 || self.type == 2) {
				var cols = [],
					vs = [];
				Object.getOwnPropertyNames(obj).forEach((key) => {
					cols.push(key);
					vs.push(obj[key]);
				});
				var sql = "insert into " + 表名 + " (" + cols.join(',') + ") Values (" + vs.join(
						',') +
					")";
				self.execSql(sql, 成功回调)
			}
		}
		/**
		 * where:" where ...."
		 */
		self.f修改对象 = function(表名, obj, 成功回调, where) {
			if (self.type == 0) return false;
			if (self.type == 3) {
				let store = get对象表(表名);

				store.put(obj).onsuccess = function(e) {
					成功回调 && 成功回调(e);
				};
			} else if (self.type == 1 || self.type == 2) {
				var cols = [];
				Object.getOwnPropertyNames(obj).forEach((key) => {
					cols.push(key + "=  '" + obj[key] + "'")
				});
				var sql = "update " + 表名 + " set " + cols.join(',') + " " + where;
				self.execSql(sql,
					成功回调)
			}
		}
		/**
		 * where:" where ...."
		 */
		self.f保存对象 = function(表名, obj, 成功回调, where) {
			if (self.type == 0) return false;
			if (self.type == 3) {

				const store = get对象表(表名);
				store.put(obj).onsuccess = function(e) {
					成功回调 && 成功回调(e);
				};

			} else if (self.type == 1 || self.type == 2) {
				if (!where)
					where = "where " + self._表池key[表名] + "='" + obj[self._表池key[表名]] + "'";
				var sql = "select count(1) as cnt from " + 表名 + " " + where;
				var success = function(tx, rs) {
					if (rs.rows.length > 0 && rs.rows.item(0).cnt > 0) {
						self.f修改对象(表名, obj, 成功回调, where)
					} else {
						self.f插入对象(表名, obj, 成功回调)
					}
				};
				self.execSql(sql, success);
			}
		}
		self.get对象 = function(表名, keyid, 获取回调) {
			if (self.type == 0) return false;
			if (self.type == 3) {
				let store = get对象表(表名);
				let req = store.get(keyid);
				req.onsuccess = function(r) {
					获取回调 && 获取回调(r.target.result);
				}
				req.onerror = function(e) {
					console.log(e);
				}
			} else if (self.type == 1 || self.type == 2) {
				var sql = "select * from " + 表名 + " where " + self._表池key[表名] + " = '" + keyid +
					"'";
				select(sql, function(list) {
					获取回调 && 获取回调(list[0]);
				});
			}
		}
		self.del对象 = function(表名, key, 删除后回调) {
			if (self.type == 0) return false;
			if (self.type == 3) {
				let store = get对象表(表名);
				console.log("删除", key)
				store.delete(key).onsuccess = function(r) {
					删除后回调 && 删除后回调(r.target.result);
				}

			} else if (self.type == 1 || self.type == 2) {
				var sql = "delete from " + 表名 + " where " + self._表池key[表名] + " = '" + key +
					"'";
				select(sql, function(list) {
					删除后回调 && 删除后回调(list[0]);
				});
			}
		}
		self.delKV = function(key, 删除后回调) {
			self.del对象(DB.键值对表, key, 删除后回调);
		}
		self.setKV = function(key, value, 设置后回调) {
			self.f保存对象(DB.键值对表, {
				id: key,
				va: value
			}, 设置后回调)
		}
		self.getKV = function(key, 查询后回调) {
			self.get对象(DB.键值对表, key, 查询后回调)
		}
		self.getKVs = function(遍历) {
			self.f遍历集合(DB.键值对表, 遍历)
		}
		self.f更新表结构 = function(版本, 建表函数, 更新结束, 更新异常) {
			return new Promise(function(ok, err) {
				//,版本,建表,打开
				open(版本, function() {
					//console.log("------------------------")
					self.f建表(DB.键值对表, {
						键: "id",
						字段: {
							id: "varchar(50)",
							va: "varchar(1000)"
						}
					});

					建表函数 && 建表函数();
				}, function(e) {
					ok(更新结束());
				}, function(e) {
					err(更新异常());
				});

			});
		}
		return self;
	}


};
export default DB;
